#pragma once
#include <mutex>
#include <condition_variable>

class RWLock {
public:
	RWLock() : rw_nwaitreaders(0), rw_nwaitwriters(0), rw_refcount(0) { }
	~RWLock() = default;
	RWLock(const RWLock&) = delete;
	RWLock& operator=(const RWLock&) = delete;

public:
	void rdlock();    /* wait for reader lock */
	bool tryrdlock(); /* try to get reader lock */
	void wrlock();    /* wait for writer lock */
	bool trywrlock(); /* try to get writer lock */
	void unlock();    /* release reader or writer lock */

private:
	std::mutex rw_mutex;
	std::condition_variable_any rw_condreaders;
	std::condition_variable_any rw_condwriters;
	int rw_nwaitreaders;                        /* the number of waiting readers */
	int rw_nwaitwriters;                        /* the number of waiting writers */
	int rw_refcount; /* 0: not locked; -1: locked by one writer; > 0: locked by rw_refcount readers */
};

class WLockGuard {
public:
	WLockGuard(RWLock &rwlock): m_rwlock(rwlock) {
		//rwlock.wrlock();
	}
	~WLockGuard() {
		//m_rwlock.unlock();
	}
private:
	RWLock& m_rwlock;
};
class RLockGuard {
public:
	RLockGuard(RWLock& rwlock) : m_rwlock(rwlock) {
		//rwlock.rdlock();
	}
	~RLockGuard() {
		//m_rwlock.unlock();
	}
private:
	RWLock& m_rwlock;
};